package org.example.exampreparationtreasure.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.example.exampreparationtreasure.mapper.IncorrectQuestionRecordMapper;
import org.example.exampreparationtreasure.mapper.QuestionCategoryMapper;
import org.example.exampreparationtreasure.model.entity.IncorrectQuestionRecord;
import org.example.exampreparationtreasure.model.entity.QuestionCategory;
import org.example.exampreparationtreasure.service.KnowledgeMasteryService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.*;

/**
 * 知识掌握度服务实现类
 * 计算用户在各知识分类的掌握程度
 */
@Service
@RequiredArgsConstructor
public class KnowledgeMasteryServiceImpl implements KnowledgeMasteryService {
	private final IncorrectQuestionRecordMapper incorrectMapper;
	private final QuestionCategoryMapper categoryMapper;

	/**
	 * 计算单个知识点的掌握度
	 * 基于错题次数计算掌握度，错题越少掌握度越高
	 *
	 * @param userId 用户ID
	 * @param knowledgeId 知识点ID
	 * @return 掌握度值(0-1)，1表示完全掌握，0表示完全未掌握
	 */
	@Override
	public double calculateMasteryLevel(Long userId, Long knowledgeId) {
		try {
			System.out.println("计算用户 " + userId + " 在知识点 " + knowledgeId + " 的掌握度");
			
			// 统计用户在指定知识点的错题次数
			Long mistakeCount = incorrectMapper.selectCount(new LambdaQueryWrapper<IncorrectQuestionRecord>()
				.eq(IncorrectQuestionRecord::getUserId, userId)
				.eq(IncorrectQuestionRecord::getCategoryId, knowledgeId));
			
			int mistakes = mistakeCount.intValue();
			System.out.println("用户 " + userId + " 在知识点 " + knowledgeId + " 的错题次数: " + mistakes);
			
			// 使用反比例函数计算掌握度：掌握度 = 1 / (1 + 错题次数)
			// 错题次数为0时掌握度为1，错题次数越多掌握度越低
			double mastery = 1.0 / (1 + mistakes);
			System.out.println("计算出的掌握度: " + mastery);
			
			return mastery;
		} catch (Exception e) {
			System.err.println("计算掌握度时发生异常: " + e.getMessage());
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 获取用户的知识掌握度映射
	 * 计算用户在所有知识分类的掌握度
	 *
	 * @param userId 用户ID
	 * @return 掌握度映射，key为分类ID，value为掌握度(0-1)
	 */
	@Override
	public Map<Long, Double> getMasteryMap(Long userId) {
		try {
			System.out.println("=== 开始计算知识掌握度 ===");
			System.out.println("用户ID: " + userId);
			
			// 获取所有知识分类
			List<QuestionCategory> all = categoryMapper.selectList(null);
			System.out.println("获取到的知识分类数量: " + all.size());
			System.out.println("知识分类列表: " + all);
			
			Map<Long, Double> map = new HashMap<>();
			// 为每个分类计算掌握度
			for (QuestionCategory c : all) {
				System.out.println("计算分类 " + c.getId() + " (" + c.getName() + ") 的掌握度");
				double mastery = calculateMasteryLevel(userId, c.getId());
				System.out.println("分类 " + c.getId() + " 的掌握度: " + mastery);
				map.put(c.getId(), mastery);
			}
			
			System.out.println("最终掌握度映射: " + map);
			System.out.println("=== 知识掌握度计算完成 ===");
			return map;
		} catch (Exception e) {
			System.err.println("=== 知识掌握度计算异常 ===");
			System.err.println("异常类型: " + e.getClass().getSimpleName());
			System.err.println("异常消息: " + e.getMessage());
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 获取用户薄弱知识点
	 * 找出用户掌握度最低的知识点，用于针对性学习
	 *
	 * @param userId 用户ID
	 * @return 薄弱知识点列表，按掌握度升序排列
	 */
	@Override
	public List<QuestionCategory> getWeakKnowledgePoints(Long userId) {
		// 获取掌握度映射
		Map<Long, Double> mm = getMasteryMap(userId);
		List<QuestionCategory> list = categoryMapper.selectList(null);
		// 按掌握度升序排序，掌握度最低的排在前面
		list.sort(Comparator.comparingDouble(c -> mm.getOrDefault(c.getId(), 0.0)));
		// 返回前5个最薄弱的知识点
		return list.subList(0, Math.min(5, list.size()));
	}

	/**
	 * 预测掌握度趋势
	 * 基于历史数据预测用户掌握度的变化趋势
	 *
	 * @param userId 用户ID
	 * @param knowledgeId 知识点ID
	 * @return 趋势分析结果，包含每日掌握度变化
	 */
	@Override
	public Map<LocalDate, Double> predictMasteryTrend(Long userId, Long knowledgeId) {
		// 生成过去7天的掌握度数据（模拟数据）
		Map<LocalDate, Double> map = new TreeMap<>();
		for (int i = 6; i >= 0; i--) {
			map.put(LocalDate.now().minusDays(i), calculateMasteryLevel(userId, knowledgeId));
		}
		return map;
	}
} 